package com.yumo.kangchenjunga.user;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.annotation.JsonView;
import com.yumo.kangchenjunga.company.NoSuchCompanyException;
import com.yumo.kangchenjunga.company.NoSuchStoreException;
import com.yumo.kangchenjunga.exception.controller.HttpBadRequestException;
import com.yumo.kangchenjunga.exception.controller.HttpNotFoundException;
import com.yumo.kangchenjunga.security.CustomUserDetails;

@RestController
@RequestMapping("/api/v1")
public final class UserController {

	@Autowired
	private UserService service;

	@GetMapping("/users/{id}")
	@JsonView(UserVo.Output.class)
	public UserVo queryById(@PathVariable int id) throws HttpNotFoundException {
		try {
			return service.queryById(id);
		} catch (NoSuchUserException e) {
			throw HttpNotFoundException.build(e, "用户 [ id: %d ] 不存在。", id);
		}
	}

	@GetMapping("/users/")
	@JsonView(UserVo.Output.class)
	public List<UserVo> list() {
		return service.list();
	}
	
	@GetMapping(value = "/users/", params = "paged")
	public Page<UserVo> query(@AuthenticationPrincipal CustomUserDetails currentUser,
			@PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.DESC) Pageable pageable) {
		if(currentUser.getCompanyId() == 1) {
			return service.pageByPrivilege(pageable.getPageNumber(), pageable.getPageSize(), "admin");
		} else {
			return service.pageByCompanyId(pageable.getPageNumber(), pageable.getPageSize(), currentUser.getCompanyId());
		}
	}

	@PostMapping("/users/")
	public UserVo create(@RequestBody UserVo user) throws HttpNotFoundException {
		try {
			return service.create(user);
		} catch (NoSuchCompanyException e) {
			throw HttpNotFoundException.build("企业 [ id: %d, name: '%s' ] 不存在。", user.companyId, user.companyName);
		} catch (NoSuchStoreException e) {
			throw HttpNotFoundException.build("门店 [ id: %d, name: '%s' ] 不存在。", user.storeId, user.storeName);
		}
	}

	@DeleteMapping("/users/{id}")
	public int delete(@PathVariable int id) throws HttpNotFoundException, HttpBadRequestException {
		try {
			int count = service.delete(id);

			if (count == 0) {
				throw HttpBadRequestException.build("该用户不允许删除");
			}

			return count;
		} catch (NoSuchUserException e) {
			throw HttpNotFoundException.build(e, "用户 [ id: %d ] 不存在。", id);
		}
	}

	@PutMapping("/users/{id}")
	public UserVo modify(@PathVariable int id, @RequestBody UserVo user)
			throws HttpNotFoundException, HttpBadRequestException {
		if (id == user.id) {
			try {
				return service.modify(user);
			} catch (NoSuchUserException | NoSuchStoreException e) {
				throw HttpNotFoundException.build(e, "用户或所在的门店不存在");
			}
		}

		throw HttpBadRequestException.build("The id in the path(%d) and body(%d) does not match.", id, user.id);
	}

	@PostMapping("/login")
	public String login(@RequestBody UserVo user, HttpSession session) {
		return service.login(user, session);
	}

	@PostMapping("/users/{userId}/password")
	public void changePassword(@PathVariable int userId, @RequestBody ChangePasswordVo vo)
			throws HttpBadRequestException, HttpNotFoundException {
		try {
			if (!service.changePassword(userId, vo)) {
				throw HttpBadRequestException.build("密码修改失败");
			}
		} catch (NoSuchUserException e) {
			throw HttpNotFoundException.build(e, "用户 [ id: %d ] 不存在。", userId);
		}
	}

	@ExceptionHandler(Exception.class)
	public void handler(Exception e, HttpServletResponse response) throws IOException {
		if (e instanceof DataIntegrityViolationException) {
			response.sendError(400, "同一公司内帐号名不能重复。");
		} else if (e instanceof IllegalArgumentException) {
			response.sendError(400, e.getMessage());
		} else {
			response.sendError(500);
		}
	}

}
